<?php
/**
 * Datatable(ajax版本)
 * 
 * @copyright  vincent 20130409
 * @license    Mediad License
 */
class Mediad2_Utility_Datatable {
	
	protected $isdebug = false;
	/**
	 * @var 起始页
	 */
	protected $indexPage;
	
	/**
	 * @var 分页数
	 */
	protected $rows;
	
	/**
	 * @var 总记录数
	 */
	protected $total=0;
	
	/**
	 * @var 总页数
	 */
	protected $pages=0;
	/**
	 * @var 当前页 
	 */
	protected $current;
	
	/**
	 * @var 前一页
	 */
	protected $back;
	
	/**
	 * @var 下一页
	 */
	protected $next;
	
	/**
	 * @var Mediad2_Service_Abstract
	 */
	protected $oservice;
	
	/**
	 * @var 分页按钮模式
	 */
	protected $template=1;
	
	/**
	 * @var 页面状态
	 */
	protected $pagestatus = "page";
	
	
	/**
	 * @var 返回标识 0:失败,1:成功
	 */
	protected $code = 0;
	
	
	protected $dataA=array();
	protected $dataB=array();
	protected $dataC=array();
	/**
	 * @var 动作
	 */
	protected $action;
	
	/**
	 * @var where条件
	 */
	protected $where=null;
	
	/**
	 * @var 客户端检索字段
	 */
	protected $rule=null;
	
	protected $condition=null;//20130427 显示类别条件
	
	/**
	 * @var ordery排序
	 */
	protected $order=" desc";//留1个空格
	
	protected $request_where;
	protected $request_order;
	protected $request_condition;
	
	/**
	 * @var session名称
	 */
	protected $keyword_row ="rows";
	
	protected $data ;
	protected $flagService = false;//true:service处理数据,false:data数据
	
	/**
	 * 
	 * @param Zend_Controller_Request_Abstract $request
	 * @param Zend_Controller_Response_Abstract $response
	 * @param array $invokeArgs
	 */
	public function __construct($object,$debug=false)
	{
		$this->isdebug = $debug;
		if(empty($object)){
			if (!is_array($object))
			var_dump("could not initialized datatable!");
// 			throw new Exception("could not initialized datatable!");	
		}else{
			if(is_array($object)){
				$this->data = $object;
			}else{
				$this->oservice = $object;
				$this->flagService = true;
			}
		}
	}
	
	
	/**
	 * 初始化
	 * 
	 * @param string $action 分页动作 	
	 * @param array  $column 	(like_column) 	检索字段 	
	 * @param string $where 查询条件
	 */
	public function init($action, $column=null, $where=null)
	{
		//[1]获取所有参数
		$this->action   = $action;
		$this->rule 	= $column;
		
		if (isset($where) && !empty($where)) {
			$this->where = $where;
		}
	}
	
	/**
	 * 创建datatable数据
	 * @param string $style 分页按钮的样式 
	 * @param string $row 每页行数 	
	 * @param string $stroage	行保存方式 	
	 * @param array $rulekey 	参数数组,(where,order,page,rows,condition) 查询条件,排序条件,当前页/跳转页,每页显示记录数,显示类别条件
	 */
	public function create($style=1, $row = 10, $storage="session", $rulekey = array("wvar"=>'',"ovar"=>'',"page"=>'',"rows"=>'',"cdit"=>'')) 
	{
		//[1.1new]
		$this->rows = $row;
		$this->template  =$style;
		
		foreach ($_GET as $key=>$var) {
			foreach ($rulekey as $index=>$var2) {//根据客户端传的参数对应赋值
				if($key == $index){
					$rulekey[$key] = $_GET[$key];
				}
			}
		}
		$wvar = $rulekey['wvar'];//客户端参数
		$ovar = $rulekey['ovar'];
		$page = $rulekey['page'];
		$rows = $rulekey['rows'];
		$condition = $rulekey['cdit'];
		
		$this->request_where = $wvar;
		$this->request_order = $ovar;
		$this->request_condition = $condition;
		
		if(isset($this->rule)){//客户端传来的检索值
			$where_word = null;
			$where_column = !empty($wvar) ? trim($wvar) : "";				//获取查询值
			if(isset($where_column) && !empty($where_column)){
				$len = count($this->rule);
				foreach ($this->rule as $key => $value) {
					$mark = " AND ";
					if($key==$len-1)
						$mark = "";
					$where_word .= sprintf("%s like '%%%s%%' %s",$value,$where_column,$mark);
				}
			}
			if(isset($where_word)){
				if(isset($this->where)){
					$this->where = $this->where.' AND '.$where_word;
				}else{
					$this->where = $where_word;
				}
			}
		}
		
		//20130427 构造显示类别 [如:有效/无效,成功/失败,未操作/已操作...]
		if(isset($condition) && !empty($condition)){
			$this->where = empty($this->where)?$condition:$this->where.' AND '.$condition;
		}
		
		$this->order 	= !empty($ovar) ? trim($ovar).$this->order : "";		//获取排序值
		$this->current 	= !empty($page) ? trim($page) : 1;				//当前页,jump时为目的页
		
		if($this->action == "jump" && isset($rows)){
			if(!empty($rows)){
				//将每页显示的记录条数保存到session/cookie中   按10,20,50行显示
				if($storage=="session"){
					$_SESSION[$this->keyword_row] = $rows;
					$this->rows 	= !empty($rows) ? trim($rows) : $row;
				}
				if($storage=="cookie"){
					//TODO:SET ROWS IN COOKIE
					$this->rows 	= !empty($rows) ? trim($rows) : $row;
				}
			}
		}
		
		if($storage=="session"){
			$session_rows = @$_SESSION[$this->keyword_row];
			if($session_rows!=null){
				$this->rows = $session_rows;
			}
		}
		
		//[1.1new]  end------------------------------------------------------------------------
		
		//[2]获取总记录数,总页数
		if ($this->flagService) {
			$result_count = $this->oservice->getCount($this->where);
			$row_count = 0;
			if ($result_count->getCode() == 1) {
				$row_count = $result_count->getData();
			}
		} else {
			$row_count = count($this->data);
		}
		
		$this->total 	= (int)($row_count); 				//总记录条数
		$this->pages 	= ceil($this->total / $this->rows );//总页数
		
		//[3]生成分页按钮变量
		switch($this->action){//根据action状态设置page
			case 'first':
			case 'init':
				$this->current = 1;
				break;
			case 'end':
				$this->current = $this->pages;
				break;
		}
		
		$this->back = $this->current-1;										//上一页
		$this->next = $this->current+1;										//下一页
		//设置取值步数
		$key_back 	= $this->current * $this->rows-$this->rows*2;		//前一页加载的数据 A
		$key_current	= $this->rows * 2;  							//当前页加载的数据 B
		$key_next 	 	= $this->rows * 3;     							//后一页加载的数据 C
		
		//当前页小于1时默认当前页为1
		if($this->current <= 1){
			$this->current 	= 1;
			$this->back = 1;
			$this->pagestatus = "first";
		}
		
		//当最后页大于总页数时，则最后页为总页数[20130705:当前页大于总页数时为最后一页,当前页等于最后一页且满足列表数时,不认为是最后一页 by vincent]
		if($this->current > $this->pages){
			$this->current 	= $this->pages;
			$this->next 	= $this->current;
			$this->pagestatus = "end";
		}
		
		//当前的数据少于指定显示的数据时给定的状态
		if($this->total < $this->rows){
			$this->pagestatus = "less";
		}
		
		//[4]分拆列表数据
		$row_start = 0;
		$row_end = 0;
	
		switch($this->action){
			case 'first':
			case 'init':
				$row_start= 0;
				$row_end = $key_current;
				break;
			case 'back':
			case 'jump':
				if($this->current > 1 ){
					$row_start= $key_back;
					$row_end = $key_next;
				}else{
					$row_start= 0;
					$row_end = $key_current;
				}
				break;
			case 'next':
				if($this->current >= $this->pages){
					$row_start= $key_back;
					$row_end = $key_current;
				}else{
					$row_start= $key_back;
					$row_end = $key_next;
				}
				break;
			case 'end':
				$row_start= $key_back;
				$row_end = $key_current;
				break;
		}
		if($this->isdebug){
			$h = new Mediad2_Utility_SmartyHelper();
			$h->log(sprintf("act:%s,where:%s,order:%s,page:%s,row:%s,requestwhere:%s,cdit:%s",$this->action,$this->where,$this->order,$this->current,$this->rows,$this->request_where,$this->request_condition));
		}
		
		//获取数据
		$splitdata = array();
		if ($this->flagService) {
			//调用service，获取数据
			$resultData = $this->oservice->fetchLimit($row_start,$row_end,$this->where,$this->order,true);
			//判断是否调用成功,调用不成功直接返回结果给客户端
			if($resultData->getCode()==0)return;
			$splitdata = $resultData->getData();
		} else {//根据传入data做切割
			foreach ($this->data as $key => $value) {
				if ($key >= $row_start && $key <= $row_end-1) {
					$splitdata[] = $value; 
				} 
			}
		}
		$this->split($this->rows,$splitdata,$this->pagestatus);
		return $this;
	}
		
	public function response(){//[5]返回客户端信息
		$data['code'] 			= $this->code;
		$data['current']    	= $this->current;			//当前页
		$data['rows']  			= $this->rows;
		$data['pages'] 			= $this->pages;
		$data['records']  		= $this->total;
		$data['template']  		= $this->template;
		$data['back']  			= $this->back;
		$data['next']  			= $this->next;
		$data['search']  		= $this->request_where;
		$data['order']  		= $this->request_order;
		$data['cdit']  			= $this->request_condition;
		$data['status']     	= $this->pagestatus;
		$data['dataA']  		= $this->dataA;
		$data['dataB']  		= $this->dataB;
		$data['dataC']  		= $this->dataC;
		//echo Zend_Json::encode($data);
		echo json_encode($data);
	}
	
	//分割数据
	private function split($rows, $data,$status){
		//拆分数据的值
		$split1 = $rows-1;
		$split2 = $rows*2-1;
		$count 	= count($data);
		
		//对数据进行分割，每N条放进一个数组里面
		for($i=0;$i<$count;$i++){
			$key = $data[$i];
			if(!$this->flagService)//将data中的model转成数组
				$key = $key->toArray();
			
			if($i>$split1 && $i<=$split2){
				$this->dataB[] = $key;
			}else if($i>$split2){
				$this->dataC[] = $key;
			}else{
				$this->dataA[] = $key;
			}
		}
		
		//对首页的数据进行重排
		switch ($status){
			case "first":
			case "less":
				$this->dataC = $this->dataB;
				$this->dataB = $this->dataA;
				$this->dataA = null;
				break;
		}
		$this->code = 1;
	}
	
	public function __get($property_name){//__get()方法用来获取私有属性
		if(isset($this->$property_name)) {
			return($this->$property_name);
		}else {
			return(null);
		}
	}
	
	public function __set($property_name, $value){//__set()方法用来设置私有属性
		$this->$property_name = $value;
	}
}

